#include "RawImage.h"
#include "NativeImage.h"
#include "DisplayContext.h"
#include "NativeImage.h"

using namespace WONAPI;


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Raw Image 32  /////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
RawImage32::RawImage32(int theWidth, int theHeight, DWORD *theImageData)
{
	mWidth = theWidth;
	mHeight = theHeight;
	mImageData = theImageData;
	if(mImageData==NULL)
		mImageData = new DWORD[theWidth*theHeight];

	mImagePtr = mImageData;
	mImageEnd = mImageData + mHeight*mWidth;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
RawImage32::~RawImage32()
{
	delete mImageData;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RawImage32::SetPixel(int x, int y, DWORD theColor)
{
	*(mImageData + y*mWidth + x) = theColor;
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
DWORD RawImage32::GetPixel(int x, int y)
{
	return *(mImageData + y*mWidth + x);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
DWORD* RawImage32::StartTraversal(int x, int y)
{
	mImagePtr = mImageData + y*mWidth + x;
	return mImagePtr;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
NativeImagePtr RawImage32::GetNative(DisplayContext *theContext)
{
/*	BITMAPINFO anInfo;
	BITMAPINFOHEADER &aHeader = anInfo.bmiHeader;
	aHeader.biSize = sizeof(BITMAPINFOHEADER);
	aHeader.biWidth = GetWidth();
	aHeader.biHeight = -GetHeight();
	aHeader.biPlanes = 1;
	aHeader.biBitCount = 32;
	aHeader.biCompression = BI_RGB;

	HBITMAP aBitmap = CreateDIBitmap(theContext->mDC,&aHeader,CBM_INIT,mImageData,&anInfo,DIB_RGB_COLORS);
	return new NativeImage(theContext, aBitmap);*/
	return NULL;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RawImage32::Draw(DisplayContext *theContext, int x, int y, int left, int top, int width, int height)
{
	NativeImagePtr aNativeImage = GetNative(theContext);
	aNativeImage->Draw(theContext,x,y,left,top,width,height);
}





///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Raw Image 8 ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
RawImage8::RawImage8(int theWidth, int theHeight, Palette *thePalette, unsigned char *theImageData)
{
	mWidth = theWidth;
	mHeight = theHeight;
	mPalette = thePalette;
	mImageData = theImageData;
	if(mImageData==NULL)
		mImageData = new unsigned char[theWidth*theHeight];

	mImagePtr = mImageData;
	mImageEnd = mImageData + mHeight*mWidth;

	mTransparentColor = -1;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
RawImage8::~RawImage8()
{
	delete mImageData;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RawImage8::SetPixel(int x, int y, DWORD theColor)
{
	*(mImageData + y*mWidth + x) = theColor;
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
DWORD RawImage8::GetPixel(int x, int y)
{
	return *(mImageData + y*mWidth + x);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
unsigned char* RawImage8::StartTraversal(int x, int y)
{
	mImagePtr = mImageData + y*mWidth + x;
	return mImagePtr;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
NativeImagePtr RawImage8::GetNative(DisplayContext *theContext)
{
	return NULL;
/*	Display *theDisplay = theContext->mDisplay;
	int theScreen = theContext->mScreen;
	int theDrawable = theContext->mDrawable;
	int theDepth = theContext->mDepth;
	Colormap xColorMap = theContext->mColormap;

	Pixmap aPixmap = XCreatePixmap(theDisplay, theDrawable, mWidth, mHeight, theDepth);
	XColor aColorTable[256];
	int aSize = mPalette->GetNumColors();
	GC xgc = XCreateGC(theDisplay, aPixmap, 0, NULL);
	
	for(int i=0; i<aSize; i++)
	{
		unsigned long aColor = mPalette->GetColor(i);
		aColorTable[i].red = (aColor&0xff)*256;
		aColorTable[i].green = ((aColor>>8)&0xff)*256;
		aColorTable[i].blue = ((aColor>>16)&0xff)*256;
		XAllocColor(theDisplay, xColorMap, &aColorTable[i]);
	}

	if(mTransparentColor!=-1)
		aColorTable[mTransparentColor].pixel = theContext->mBlackPixel;

	unsigned char *anImagePtr = mImageData;
	for(int y=0; y<mHeight; y++)
	{
		for(int x=0; x<mWidth; x++)
		{
			XSetForeground(theDisplay, xgc, aColorTable[*anImagePtr].pixel);
			XDrawPoint(theDisplay, aPixmap, xgc, x, y);
			anImagePtr++;
		}
	}

	XFreeGC(theDisplay, xgc);

	Pixmap aTransparentMask = 0;
	if(mTransparentColor!=-1)
	{
		RawImage1Ptr aMask = new RawImage1(mWidth,mHeight);

		unsigned char *aSrcPtr = mImageData;
		aMask->StartTraversal();
		while(aMask->HasMorePixels())
		{
			if(*(aSrcPtr++)==mTransparentColor)
				aMask->SetPixel(true);

			aMask->NextPixel();
		}

		aTransparentMask = aMask->GetMask(theContext);
	}

	return new NativeImage(theContext, mWidth, mHeight, aPixmap, aTransparentMask);*/
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RawImage8::Draw(DisplayContext *theContext, int x, int y, int left, int top, int width, int height)
{
	NativeImagePtr aNativeImage = GetNative(theContext);
	aNativeImage->Draw(theContext,x,y,left,top,width,height);
}



///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Raw Image 1 ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
RawImage1::RawImage1(int theWidth, int theHeight, unsigned char *theImageData)
{
	mWidth = theWidth;
	mHeight = theHeight;
	mImageData = theImageData;

	int aWidth = mWidth;
//	int aWidth = mWidth/8;
//	if(mWidth%8!=0)
//		aWidth++;

	mRowPad = 0;
//	if(aWidth%4!=0)
//		mRowPad=(4-aWidth%4);

	mRowSize = aWidth + mRowPad;
	mRowPad++; // gets added to mImagePtr when it reaches the last pixel on the row

	int aSize = mRowSize*theHeight;
	if(mImageData==NULL)
	{
		mImageData = new unsigned char[aSize];
		memset(mImageData,0,aSize);
	}

	mImagePtr = mImageData;
	mImageEnd = mImageData + aSize;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
RawImage1::~RawImage1()
{
	delete mImageData;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RawImage1::SetPixel(int x, int y, bool on)
{

	int aMask = (1<<(7-((x>>3)&0x7))); // 1<<(7-(x%8))
	if(on)
		*(mImageData + y*mRowSize + x/8) |= aMask;
	else
		*(mImageData + y*mRowSize + x/8) &= ~aMask;
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool RawImage1::GetPixel(int x, int y)
{
	int aMask = (1<<(7-((x>>3)&0x7))); // 1<<(7-(x%8))
	return (*(mImageData + y*mRowSize + x/8) & aMask)?true:false;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
unsigned char* RawImage1::StartTraversal(int x, int y)
{
	mCount = 0;
	mMask = (1<<(7-((x>>3)&0x7))); // 1<<(7-(x%8))
	mImagePtr = (mImageData + y*mRowSize + x/8);
	return mImagePtr;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/*
Pixmap RawImage1::GetMask(DisplayContext *theContext)
{
	return NULL;
	Display *theDisplay = theContext->mDisplay;
	int theScreen = DefaultScreen(theDisplay);

	unsigned long white = theContext->mWhitePixel;
	unsigned long black = theContext->mBlackPixel;

	Pixmap aMask = XCreatePixmap(theDisplay, theContext->mDrawable, mWidth, mHeight, 1);

	GC xgc = XCreateGC(theDisplay, aMask, 0, NULL);
	
	unsigned char *anImagePtr = mImageData;
	for(int y=0; y<mHeight; y++)
	{
		for(int x=0; x<mWidth; x++)
		{
			if(*anImagePtr)
				XSetForeground(theDisplay, xgc, white);
			else
				XSetForeground(theDisplay, xgc, black);

			XDrawPoint(theDisplay, aMask, xgc, x, y);
			anImagePtr++;
		}
	}

	XFreeGC(theDisplay, xgc);
	return aMask;

}*/

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
NativeImagePtr RawImage1::GetNative(DisplayContext *theContext)
{
//	return new NativeImage(theContext,mWidth,mHeight,GetMask(theContext));
	return NULL;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RawImage1::Draw(DisplayContext *theContext, int x, int y, int left, int top, int width, int height)
{
	NativeImagePtr aNativeImage = GetNative(theContext);
	aNativeImage->Draw(theContext,x,y,left,top,width,height);
}
/*
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
Pixmap GifImage::GetTransparentMask(Drawable theDrawable)
{
	if(mTransparentColor==-1)
		return 0;

	if(mTransparentMask!=0)
		return mTransparentMask;

	Display *theDisplay = WONAPI::Window::mDisplay;
	int theScreen = DefaultScreen(theDisplay);

	mTransparentMask = XCreatePixmap(theDisplay, theDrawable, mWidth, mHeight, 1);
	unsigned long black = BlackPixel(theDisplay, theScreen);
	unsigned long white = WhitePixel(theDisplay, theScreen);

	GC xgc = XCreateGC(theDisplay, mTransparentMask, 0, NULL);
	
	unsigned char *anImagePtr = mImage;
	for(int y=0; y<mHeight; y++)
	{
		for(int x=0; x<mWidth; x++)
		{
			if(*anImagePtr==mTransparentColor)
				XSetForeground(theDisplay, xgc, white);
			else
				XSetForeground(theDisplay, xgc, black);

			XDrawPoint(theDisplay, mTransparentMask, xgc, x, y);
			anImagePtr++;
		}
	}

	XFreeGC(theDisplay, xgc);

	return mTransparentMask;
}
*/
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
